查看原文
其他

Tornado.cash 新旧版机制研究

mazemax.eth TripleAAA 2022-08-25
  1. 功能

    Tornado.cash是一个混币协议,其核心是利用零知识证明zk snark技术,来解决以太坊上用户多个地之间转移代币的隐私保护问题。旧版本在2019年投入使用,新版本在2021年底开始beta版使用。旧版本从最早支持以太坊主链(同时支持ETH和多种ERC20代币),到目前已经支持了多种主流链(包括Polygon、BSC等)。旧版本已经完全实现了去中心化,没有后端服务器,链上合约开源且无私钥或多签控制协议,前端代码开源且完全托管在IPFS媒介中。迄今为止,没有被纰漏过重大bug,且广受黑客青睐。新版本在旧版本验证机制的基础上,引入了两个新功能,包括任意代币数量的充提和隐蔽转移(Shield Transfer)。同时使用了Omnibridge跨链桥,并把主体功能部署在了Gnosis Chain上。目前新版本由社区投票掌握,多签可以控制协议相关功能,并没有做到完全去中心化。


  2. 旧版

  • 结构:


  • 角色:

    • 用户:一般有多个地址,部分地址用来向Tornado中存币。另一部分地址用来接受混币后的代币。为了保护隐私,这两种地址应该不存在任何关联。例如,A和B两地址之间存在过链上转账记录,或者和同一个交易所地址有过充提记录,很容易被关联起来,进而破坏了混币的效果。

    • Pools:当前以太坊链存在4个存储ETH池合约,分别用来接收和提币0.1、1、10、100 ETH的单笔交易。旧版不支持用户充值任意数量的ETH(为了增强隐私性,使得充提币记录看起来都是一样的)。

    • Router:路由合约。由于有多个Pool合约,为了方便起见,用户统一从一个合约地址作为入口,这个入口就是Router,用来中转用户的请求到合适的Pool合约。

    • Relayer:中继人。也是为了加强隐私而设立的。因为提币的时候,也需要一个地址来发起交易,而这个交易需要一点ETH作为gas手续费。那么不可避免的需要有人通过一些路径把这笔gas充值到这个提币地址中(例如对于同一个用户来讲,一般从同一个交易所账户提币到不同链上账户,这样链上账户间就有可能被关联,从而导致隐私性受损)。为了解决这个问题,Tornado协议使用了Relayer,让Relayer机器人代替用户发送这笔提币交易到用户指定的收款地址中,同时会奖励给Relayer一定的ETH奖励(一般为提币总金额的0.4%左右)。这样能很好的保护用户隐私。Relayer机器人是中立的,一般通过质押一定的Torn代币才能成为Relayer。


  • 存款:

    • 充提币的全过程只涉及到合约和前端代码两部分,Tornado并没有自己的服务器来储存任何数据。所有的计算也发生在前端代码和合约中,例如计算零知识证明circuit的计算写在前端代码里,计算和存储Merkel Tree和验证Proof的有效性写在了链上合约中。前端代码和素材也被托管在了IPFS去中心化媒介中,Tornado项目方并没有前端代码托管服务器。所以整个项目(尤其是老版)的去中心化程度是很高的。

    • 存款调用合约中的deposit方法,用户发交易时需要选定ETH Pool并充值固定数量的ETH,(通过Router合约作为发起并中转到Pool合约)。存款的同时会链下生成一个Note和与之关联的commitment哈希。Note相当于用户的存款凭证(也可以理解成私钥),用于在提款时提供这个Note来链下生成零知识证明的Proof,然后使用这个Proof通过链上的验证,证明这个Note是有效的。commitment哈希用来确认链上的存款状态,具体是把这个哈希当作一个新的叶子节点插入到链上合约储存的Merkel Tree中(_insert方法就是用来干这个的),所以更新这个Merkel Tree的root节点的同时也完成了ETH的deposit,这样就能确认这笔充值在链上是生效的了。

    • Note很关键,必须放在安全的地方秘密存储。如果丢失或者被窃,原用户就永远无法取出这笔存款。


  • 提款:

    • 只要拥有了未提款过的Note,任何人都能提款ETH到指定的地址。

    • 提款用户发起提款申请,这个时候可以选择使用Relayer帮忙发起交易,或者不使用Relayer,自己花Gas完成操作。为了保护隐私,这里建议还是尽量使用Relayer,同时recipient地址也就是接收地址用未曾发过交易的地址。

    • 提款用户持有Note,这个Note与nullifierHash相关联,且结合root、recipient、relayer、fee、refund等数据,能通过zk snark circuit算法链下构造出一个Proof。如果此时选定了Relayer机器人,就将构造好的上述数据连同Proof发给Relayer,然后由他完成这笔交易。

    • recipient接收人地址、relayer地址,由提款用户自行指定。一旦通过Note计算好Proof后,就可以发起提款申请。此时Relayer地址会代替用户完成提款操作,Pool中的对应金额的ETH会发送给:a. 用户指定的recipient地址  b. 部分ETH会以小费的形式奖励给Relayer地址。

    • 需要注意的是,提款时,Tornado前端页面会提示Time passed和Subsequent deposits。也就是这个Note的存款至今的时间,和在这段时间内已经存过的其他deposits数量。而时间越长、deposits数量越多,越能打破充币和提币地址间的相关联性,越能更好的保护隐私。所以充提币的时间间隔,应尽量拉长。


  1. 新版

  • 结构:蓝色为充币过程,红色为提款过程,黑色为隐蔽转账(shielded transfer)过程


  • 角色:

    • Shielded Address:这是Nova版本的新增功能。任何用户在首次使用新版本时会自动创建一个新的地址,也就是这个Shielded Address,和这个地址对应的私钥。这个私钥充当着老版本中的Note功能。Shielded Address伴随第一笔deposit交易,会调用Tornado.cash Nova WETH Pool合约中的register方法来把这个地址注册在这个合约中,并且把owner赋予为L1链的存款者地址,也就是user地址。所以在之后,只有这个user地址或者任何持有这个Shielded Address私钥的地址,才有权限转移和提款代币。简而言之,就是创建了一个新的隐私地址的私钥(需要妥善保存),并且把这个隐私地址与user地址绑定在一起,代替了老版本中的Note。这样无论使用多少次充提币的功能,只要一个隐私地址私钥就足够了,相对于之前N多个Note来说,方便了不少。且由于使用了zk snark进行零知识证明与相同的验证机制(Verify2合约与Verify16合约),Gnosis Chain端安全性上也有同样的保障。

    • Tornado.cash Nova WETH Pool:这是部署在Gnosis Chain(xDai)链的WETH代币池地址。与老版本中的各个Pool合约功能一样,主要功能就是充币和提币。这里面不同点在于,老版本中每个充值或提币的金额是固定数量的ETH,而新版本里面,没有对这个数量进行限制,用户可以自行定义想要充值和提币的数量(目前单笔最小0.05ETH,最大不超过10ETH,也可以通过社区投票自治,多签执行来改变这个最大限额),所以新版本也没有多个Pool合约,所有都与这一个池子进行交互。

    • L1 Helper:用户充币时,直接与这个L1 Helper合约交互。可以将用户的ETH转化成WETH并发送跨链桥合约。

    • L1 Unwrapper:用户提币时,由Relayer机器人发起,跨链桥合约调用提币方法。之后将WETH转化成ETH,并发送给接收地址,同时发送小费给Relayer。

    • L1 Omnibridge:部署在以太坊的跨链桥合约。主要用于从L1 Helper中接收用户存款的ETH并发送链上事件(用于通知Gnosis Chain跨链桥生成相应资产)。也负责把WETH发送给L1 Unwrapper以完成提币。

    • Gnosis Chain Omnibridge:部署在Gnosis链的跨链桥合约。主要用于接收L1跨链桥信息并mint新增WETH给到Nova Pool合约,也负责在用户发起提款时,销毁从Nova Pool中发过来的WETH,并发出链上事件通知L1 Omnibridge来完成提款操作。


  • 存款:

    • 初次使用会自动生成一个Shielded Address和这个地址的私钥。私钥在功能上相当于旧版本中的Note。

    • 如图中蓝色箭头的指示方向,在新版本中,在L1上充币,本质上是把ETH存在了跨链桥合约中,然后在Gnosis链上新mint一个WETH凭证,并没有把ETH存在L1的某个混币池子中。

    • 其流程是用户直接与L1 Helper交互(触发wrapAndRelayTokens方法),把WETH发送给L1跨链桥储存,同时在Gnosis Chain的Nova Pool合约中触发onTokenBridged方法来接收L2新增的WETH到池子中并记录这个充值状态(充值状态的确认在原理上和旧版本一样,都是把commitment哈希插入到Merkel Tree中记录状态的)。


  • 提款:

    • 提款首先依赖Shield Address私钥持有人构造Proof,参数和旧版本类似。Proof用来在链上验证提款的真实性。

    • 构造好Proof之后,如图中红色箭头指示,提款的操作是在Gnosis Chain的选定的Relayer机器人发起的(这个机器人花费的小费相对以太坊链就小的多了)。将Nova Pool中的WETH发给L2跨链桥,并销毁WETH,同时发给L1跨链桥提币请求。

    • 此时L1得到提币消息后,也需要第二个Relayer机器人发起,来完成提币到用户指定地址的交易(此时的小费和旧版本数量类似,并没有很节省成本)。


  • 隐私转账(shielded transfer):

    • 这是Nova新增的功能之一。以往转账的时候需要用户把资金从混币池中提币到另一个地址。在这个新版本中,允许用户资金在不离开Gnosis Nova Pool的情况下,进行池内转账到一个shielded address(前提是这个地址也register过Nova Pool了),转币数量也是任意的,同时需要支付Relayer一笔金额很低的小费。


  1. 总结

由于新版本采用了Omni跨链桥,所以跨链桥面临的安全性问题,Tornado Nova都会面临。新版本的主体功能,也就是WETH的存款池子 Nova Pool本质上是Gnosis链上对L1存款记账的映射。这样做的好处是,由于在Gnosis链上操作,让后续池内转账shield transfer的成本更低。另一个好处就是引入了shield address的私钥,来代替旧版本中的神秘代码Note,简化了用户每次存储的门槛(只需要保管好一个私钥就够了,不用每笔都记录Note)。坏处就是由于使用了跨链桥牺牲了安全性,并且也不能降低充币和提币的成本(同样依赖L1的Relayer机器人)。对于用户来讲,旧版本更可靠,适合低频率大资金的操作需求;新版本更灵活,适合高频率小资金的操作需求。



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存